--[[
编码: WMS-08-10
作者:HAN
日期:2025-1-29
入口函数: EQActionProcess
功能说明:
变更记录:
--]]
wms_op = require( "wms_operation" )
wms_dev = require( "wms_devcomm" )
wms_task = require( "wms_task" )
wms_wh = require( "wms_wh" )
function EQActionProcess ( strLuaDEID )
local nRet, strRetInfo
-- step1 获取设备动作队列 MQ_EQAction
local mq_eq_action
nRet, mq_eq_action = m3.GetSysCurEditDataObj( strLuaDEID, "MQ_EQAction ")
if ( nRet ~= 0 ) then lua.Error( strLuaDEID, debug.getinfo(1), mq_eq_action ) end
-- step2 AGV传上来的数据保存在 mq_eq_action.data 是下面这样一段Json字符串
-- {"State":"%d","No":"%s","Ext1":"%s","Ext2":"%s","Ext3":"%s","ForkliftNo":"%d","ErrCode":"%d","ExtData":"%d"}
local agv_action, success
success, agv_action = pcall( json.decode, mq_eq_action.data)
if ( success == false ) then lua.Error( strLuaDEID, debug.getinfo(1), "动作队列中的字符串是不合法的JSON格式! "..mq_eq_action.data ) end
-- 注意 动作码 是数值类型
local nActionCode = lua.StrToNumber( agv_action.State )
local strTaskCode = agv_action.No
local strForkliftNo = agv_action.ForkliftNo
-- step3. 获取任务信息,如果有任务编码检查一下任务是否存在
-- 检查任务的状态是否=完成,已经完成的任务也不能继续接收 action
local task = {}
if ( strTaskCode ~= '') then
nRet, task = wms_task.GetInfo( strLuaDEID, strTaskCode )
-- 如果任务不存在或出错, 返回
if ( nRet ~= 0 ) then lua.Error( strLuaDEID, debug.getinfo(1), task ) end
else
task = nil
end
if ( task == nil ) then lua.Error( strLuaDEID, debug.getinfo(1), "设备动作队列中任务编码为空或任务编码无效! " ) end
-- V3.1
if ( task.bs_state == wms_base.Get_nConst(strLuaDEID, "任务状态-完成") ) then
lua.Error( strLuaDEID, debug.getinfo(1), "任务编码 = '"..task.code.."' 的任务已经完成,无法继续接受任务活动!")
end
if ( strForkliftNo == nil or strForkliftNo == '') then
lua.Error( strLuaDEID, debug.getinfo(1), "HostToAGV 回调接口数据不完整,少车辆号(ForkliftNo)! ".. mq_eq_action.data )
end
-- step4 根据设备的动作类型进行处理
local strActionValue = '' -- 附加值
-- 以下这些动作要判断一下任务里是否已经有,有返回
if ( nActionCode == wms_base.Get_nConst( strLuaDEID, "AGV-开始运行" ) or nActionCode == wms_base.Get_nConst( strLuaDEID, "AGV-搬运完成" ) or
nActionCode == wms_base.Get_nConst( strLuaDEID, "AGV-取货请求" ) ) then
nRet, strRetInfo = wms_task.Action_Exist( strLuaDEID, task.code, nActionCode )
if ( nRet ~= 0 ) then lua.Error( strLuaDEID, debug.getinfo(1), "任务动作检查时出错! "..strRetInfo ) end
if ( strRetInfo == "yes" ) then return end
end
-- 1
if ( nActionCode == wms_base.Get_nConst( strLuaDEID, "AGV-开始运行" ) ) then
-- 车辆开始执行
-- 需要给任务赋值车辆代码,开始时间
if ( task.eq_code ~= "" ) then
-- 如果任务已经绑定了车辆,报错
lua.Error( strLuaDEID, debug.getinfo(1), "任务编码='"..task.code.."'的任务已经绑定了设备,设备编码='"..task.eq_code.."'" )
end
task.eq_code = agv_action.ForkliftNo
task.bs_state = wms_base.Get_nConst(strLuaDEID, "任务状态-执行")
task.start_time = os.date("%Y-%m-%d %H:%M:%S")
nRet, strRetInfo = wms_task.Update( strLuaDEID, task )
if ( nRet ~= 0 ) then lua.Error( strLuaDEID, debug.getinfo(1), "更新任务信息失败!"..strRetInfo ) end
-- 2
elseif ( nActionCode == wms_base.Get_nConst( strLuaDEID, "AGV-搬运完成" ) ) then
-- AGV 搬运完成
nRet, strRetInfo = wms.wms_TaskFinish( strLuaDEID, task.code )
if ( nRet ~= 0 ) then
-- V7.2
local setAttr, strErr
setAttr = "S_ERR = '".."在设备动作监听脚本 WMS-107-02 中执行 wms_TaskFinish 失败! 原因:"..strRetInfo.."'"
nRet, strErr = mobox.addProcSQL2( "Task", task.id, setAttr )
if ( nRet ~= 0 ) then
lua.Error( strLuaDEID, debug.getinfo(1), "addProcSQL2 失败!"..strErr )
end
lua.Error( strLuaDEID, debug.getinfo(1), "任务编码='"..task.code.."'的任务设置完成失败!"..strRetInfo )
end
-- 4
elseif ( nActionCode == wms_base.Get_nConst( strLuaDEID, "AGV-取货完成" ) ) then
-- AGV取货完成,给PLC一个完成信号
-- step1 获取线体编号 line_seg_code
local line_seg_code
-- 如果是入库搬运需要和输送线进行交互,如果出库不需要直接从货架取
if ( task.type == wms_base.Get_nConst( strLuaDEID, "任务类型-AGV入库搬运")) then
nRet, line_seg_code = XX_GetLineSegCodeByLocCode( strLuaDEID, task.start_loc_code )
if ( nRet ~= 0 ) then
lua.Error( strLuaDEID, debug.getinfo(1), "任务编码 = '"..strTaskCode.."' 的任务属性早中起始货位不完整! "..line_seg_code )
end
--PLC写入的完成信号
local body = {}
body.device_code = "S7_Line_01"
body.comm_code = line_seg_code.."_FINISH"
body.value = {}
body.value[1] = wms_base.Get_nConst( strLuaDEID, "PLC信号-AGV出框完成" )
wms_dev.WriteS7PLCCommsData( strLuaDEID, body )
end
-- 货位和托盘解绑
nRet, strRetInfo = wms_wh.Loc_Container_Unbinding( strLuaDEID, task.start_loc_code, task.cntr_code, "绑定解绑方法-系统", task.code.."取货完成" )
if ( nRet ~= 0 ) then lua.Error( strLuaDEID, debug.getinfo(1), '货位容器解绑失败!'..strRetInfo ) end
-- 6
elseif ( nActionCode == wms_base.Get_nConst( strLuaDEID, "AGV-卸货完成" ) ) then
-- AGV卸货完成
-- 需要判断一下 当前 task 的任务类型
if ( task.type == wms_base.Get_nConst( strLuaDEID, "任务类型-AGV入库搬运")) then
-- 货位和托盘进行绑定
-- 从任务中获取 目标位置,目标位置和托盘进行绑定
-- 从作业对象中获取容器编码(目前只是单个容器)
local operation = {}
nRet, operation = wms_op.GetInfo( strLuaDEID, task.op_code )
if ( nRet ~= 0 ) then lua.Error( strLuaDEID, debug.getinfo(1), "获取编码='"..task.op_code.."'的作业对象失败! "..operation ) end
-- 货位和托盘进行绑定
nRet, strRetInfo = wms_wh.Loc_Container_Binding( strLuaDEID, task.end_loc_code, operation.cntr_code, "绑定解绑方法-系统", task.code.."卸货完成" )
if ( nRet ~= 0 ) then lua.Error( strLuaDEID, debug.getinfo(1), '货位容器绑定失败!'..strRetInfo ) end
elseif ( task.type == wms_base.Get_nConst( strLuaDEID, "任务类型-AGV出库搬运")) then
-- AGV 已经把出库货品搬运到 线体出口
-- 需要给PLC发一个进框完成信号
local line_seg_code
nRet, line_seg_code = XX_GetLineSegCodeByLocCode( strLuaDEID, task.end_loc_code )
if ( nRet ~= 0 ) then
lua.Error( strLuaDEID, debug.getinfo(1), "任务编码 = '"..strTaskCode.."' 的任务属性早中起始货位不完整! "..line_seg_code )
end
-- 组织给PLC写入的完成信号
local body = {}
body.device_code = "S7_Line_01"
body.comm_code = line_seg_code.."_FINISH"
body.value = {}
body.value[1] = wms_base.Get_nConst( strLuaDEID, "PLC信号-AGV进框完成" )
lua.Debug( strLuaDEID, debug.getinfo(1), "AGV进框完成 body", lua.table2str(body))
wms_dev.WriteS7PLCCommsData( strLuaDEID, body )
else
lua.Error( strLuaDEID, debug.getinfo(1), "任务编码 = '"..strTaskCode.."' 的任务类型不正确! " )
end
-- 1101
elseif ( nActionCode == wms_base.Get_nConst( strLuaDEID, "AGV-取货请求" ) ) then
-- AGV取货请求
-- 根据【任务】类型来判断 线体出入口 位置
-- 如果是入库作业,任务的开始位置是线体端,如果是出库任务的目标位置是线体端
if ( task.type == wms_base.Get_nConst( strLuaDEID, "任务类型-AGV入库搬运")) then
line_loc_code = task.start_loc_code
else
lua.Error( strLuaDEID, debug.getinfo(1), "任务编码 = '"..strTaskCode.."' 的任务类型不正确! " )
end
nRet, line_seg_code = XX_GetLineSegCodeByLocCode( strLuaDEID, line_loc_code )
if ( nRet ~= 0 ) then
lua.Error( strLuaDEID, debug.getinfo(1), "任务编码 = '"..strTaskCode.."' 的任务属性早中起始货位不完整! "..line_seg_code )
end
-- 获取 线体信号,如果是有框,发出出框请求并且 AGV 的搬运任务状态设置为 "等待出框"
local state = wms_dev.ReadS7PLCCommsData( strLuaDEID, "S7_Line_01", line_seg_code..'_STUS' )
-- 判断线体 (1) 是否空闲 = 0(2)是否有框 = 1 -- 有框 (3)是否允许出框 = 1 -- 允许出框
if ( state[wms_base.Get_nConst(strLuaDEID,"输送线-线体状态")] == 0 and
state[wms_base.Get_nConst(strLuaDEID,"输送线-光电信号")] == 1 and
state[wms_base.Get_nConst(strLuaDEID,"输送线-线体信号")] == 1 ) then
-- 通知 AGV 开始取货
local strXml
-- ParamNo='9 继续取货
strXml = ""
nRet, strRetInfo = wms.wms_ChangeNdcOrderParameter( task.factory, task.schedule_type, strXml )
if ( nRet ~= 0 ) then lua.Error( strLuaDEID, debug.getinfo(1), "HostToAGV推送指令失败!"..strRetInfo) end
else
return
end
-- 1102
elseif ( nActionCode == wms_base.Get_nConst( strLuaDEID, "AGV-卸货请求" ) ) then
-- AGV卸货请求
-- 如果是出库作业,任务的终止位置是线体端
if ( task.type == wms_base.Get_nConst( strLuaDEID, "任务类型-AGV出库搬运")) then
line_loc_code = task.end_loc_code
else
lua.Error( strLuaDEID, debug.getinfo(1), "任务编码 = '"..strTaskCode.."' 的任务类型不正确! " )
end
nRet, line_seg_code = XX_GetLineSegCodeByLocCode( strLuaDEID, line_loc_code )
if ( nRet ~= 0 ) then
lua.Error( strLuaDEID, debug.getinfo(1), "任务编码 = '"..strTaskCode.."' 的任务属性早中终点货位不完整! "..line_seg_code )
end
-- 获取 线体信号,如果是有框,发出进框请求并且 AGV 的搬运任务状态设置为 "等待出框"
local state = wms_dev.ReadS7PLCCommsData( strLuaDEID, "S7_Line_01", line_seg_code..'_STUS' )
-- 判断线体 (1) 是否空闲 = 0(2)是否有框 = 0 -- 无框 (3)是否允许进框 = 2 -- 允许进框
if ( state[wms_base.Get_nConst(strLuaDEID,"输送线-线体状态")] == 0 and
state[wms_base.Get_nConst(strLuaDEID,"输送线-光电信号")] == 0 and
state[wms_base.Get_nConst(strLuaDEID,"输送线-线体信号")] == 2 ) then
-- 通知 AGV 开始卸货
local strXml
-- ParamNo='9 继续卸货
strXml = ""
lua.Debug( strLuaDEID, debug.getinfo(1), "ChangeNdcOrderParameter", strXml )
--[[
nRet, strRetInfo = wms.wms_ChangeNdcOrderParameter( task.factory, task.schedule_type, strXml )
if ( nRet ~= 0 ) then lua.Error( strLuaDEID, debug.getinfo(1), "HostToAGV推送指令失败!"..strRetInfo) end
--]]
else
-- 如果线体的信号不能满足就返回,等下一次信号
return
end
end
-- 根据动作码获取动作名称
local task_action = m3.AllocObject(strLuaDEID,"Task_Action")
task_action.task_code = strTaskCode
task_action.action_code = nActionCode
task_action.eq_code = task.eq_code
task_action.eq_type_name = mq_eq_action.eq_type_name
task_action.data = lua.FormatJsonString( mq_eq_action.data )
task_action.value = strActionValue
nRet, strRetInfo = m3.CreateDataObj( strLuaDEID, task_action )
if ( nRet ~= 0 ) then lua.Error( strLuaDEID, debug.getinfo(1), '创建【任务动作】对象失败!'..strRetInfo ) end
end